package ReentrantLock_3;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class BoundedBuffer {
    private final String[] buffer;
    private int putIndex, takeIndex, count;
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();

    public BoundedBuffer(int size) {
        buffer = new String[size];
    }

    public void put(String item) throws InterruptedException {
        lock.lock();
        try {
            while (count == buffer.length) {
                notFull.await();
            }
            buffer[putIndex] = item;
            putIndex = (putIndex + 1) % buffer.length;
            count++;
            System.out.println(Thread.currentThread().getName() + " 生产: " + item);
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    public String take() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0) {
                notEmpty.await();
            }
            String item = buffer[takeIndex];
            takeIndex = (takeIndex + 1) % buffer.length;
            count--;
            System.out.println(Thread.currentThread().getName() + " 消费: " + item);
            notFull.signal();
            return item;
        } finally {
            lock.unlock();
        }
    }
}

public class Condition使用_有限缓冲区 {
    public static void main(String[] args) {
        final BoundedBuffer buffer = new BoundedBuffer(5);

        // 创建15个生产者线程
        for (int i = 0; i < 15; i++) {
            new Thread(new Runnable() {
                public void run() {
                    try {
                        for (int j = 0; j < 3; j++) {
                            buffer.put("产品-" + Thread.currentThread().getName() + "-" + j);
                            Thread.sleep(50);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "生产者-" + i).start();
        }

        // 创建15个消费者线程
        for (int i = 0; i < 15; i++) {
            new Thread(new Runnable() {
                public void run() {
                    try {
                        for (int j = 0; j < 3; j++) {
                            buffer.take();
                            Thread.sleep(100);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "消费者-" + i).start();
        }
    }
}